package com.xiehua.task.agent;

import com.xiehua.task.protocol.TaskPacket;
import org.tio.core.ChannelContext;
import org.tio.core.GroupContext;
import org.tio.core.exception.AioDecodeException;
import org.tio.core.intf.Packet;
import org.tio.server.intf.ServerAioHandler;

import java.nio.ByteBuffer;

public abstract class PostMan implements ServerAioHandler {


    /**
     * 解码：把接收到的ByteBuffer，解码成应用可以识别的业务消息包
     * 消息头：type + bodyLength
     * 消息体：byte[]
     */
    @Override
    public TaskPacket decode(ByteBuffer buffer, ChannelContext channelContext) throws AioDecodeException {
        int readableLength = buffer.limit() - buffer.position();
        if (readableLength < TaskPacket.HEADER_LENGHT) return null;
        byte magicNum = buffer.get();
        byte type = buffer.get();
        int bodyLength = buffer.getInt();
        byte[]  cid= new byte[32];
        buffer.get(cid);
        byte[] sign = new byte[32];
        buffer.get(sign);
        if (bodyLength < 0) throw new AioDecodeException("bodyLength [" + bodyLength + "] is not right, remote:" + channelContext.getClientNode());
        int neededLength = TaskPacket.HEADER_LENGHT + bodyLength;
        int test = readableLength - neededLength;
        if (test < 0) {
            return null;// 不够消息体长度(剩下的buffe组不了消息体)
        } else {
            TaskPacket imPacket = new TaskPacket(magicNum,type,cid,sign);
            if (bodyLength > 0) {
                byte[] dst = new byte[bodyLength];
                buffer.get(dst);
                imPacket.setBody(dst);
            }
            return imPacket;
        }
    }

    /**
     * 编码：把业务消息包编码为可以发送的ByteBuffer
     * 消息头：type + bodyLength
     * 消息体：byte[]
     */
    @Override
    public ByteBuffer encode(Packet packet, GroupContext groupContext, ChannelContext channelContext) {
        TaskPacket xiehuakPacket = (TaskPacket) packet;
        byte[] body = xiehuakPacket.getBody();
        int bodyLen = 0;
        if (body != null) bodyLen = body.length;
        //总长度是消息头的长度+消息体的长度
        int allLen = TaskPacket.HEADER_LENGHT + bodyLen;
        ByteBuffer buffer = ByteBuffer.allocate(allLen);
        buffer.order(groupContext.getByteOrder());

        buffer.put(xiehuakPacket.getMagicNum());
        buffer.put(xiehuakPacket.getType());
        buffer.putInt(bodyLen);
        if(xiehuakPacket.getCid() != null) buffer.put(xiehuakPacket.getCid());
        if(xiehuakPacket.getSign() != null) buffer.put(xiehuakPacket.getSign());
        if (body != null) buffer.put(body);
        return buffer;
    }

}
